import { WebSocketServer } from 'ws';
import jwt from 'jsonwebtoken';
import { sshService } from '../services/sshService.js';
import { monitorService } from '../services/monitorService.js';
import { Server } from '../models/Server.js';
import { Session } from '../models/Session.js';
import { log } from '../utils/logger.js';
import { v4 as uuidv4 } from 'uuid';

const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';

/**
 * WebSocket SSH处理器
 */
export function setupSSHWebSocket(server) {
  const wss = new WebSocketServer({ 
    server,
    path: '/ws/ssh'
  });

  log.system('WebSocket服务启动成功', { path: '/ws/ssh' });

  wss.on('connection', async (ws, req) => {
    let userId = null;
    let connectionId = null;
    let monitorInterval = null;

    try {
      // 从查询参数获取token
      const url = new URL(req.url, `http://${req.headers.host}`);
      const token = url.searchParams.get('token');
      const serverId = parseInt(url.searchParams.get('serverId'));

      if (!token || !serverId) {
        ws.send(JSON.stringify({
          type: 'error',
          message: '缺少token或服务器ID'
        }));
        ws.close();
        return;
      }

      // 验证token
      let decoded;
      try {
        decoded = jwt.verify(token, JWT_SECRET);
        userId = decoded.userId;
      } catch (error) {
        ws.send(JSON.stringify({
          type: 'error',
          message: 'Token无效或已过期'
        }));
        ws.close();
        return;
      }

      // 验证会话
      const session = Session.findByToken(token);
      if (!session) {
        ws.send(JSON.stringify({
          type: 'error',
          message: '会话已失效'
        }));
        ws.close();
        return;
      }

      // 获取服务器配置
      const serverConfig = await Server.getById(serverId, userId);
      if (!serverConfig) {
        ws.send(JSON.stringify({
          type: 'error',
          message: '服务器不存在'
        }));
        ws.close();
        return;
      }

      log.ssh('WebSocket连接建立', { userId, serverId });

      // 创建SSH连接
      connectionId = uuidv4();
      
      ws.send(JSON.stringify({
        type: 'status',
        message: '正在连接服务器...'
      }));

      const client = await sshService.connect(connectionId, serverConfig, userId);
      const stream = await sshService.createShell(connectionId);

      ws.send(JSON.stringify({
        type: 'connected',
        message: '连接成功',
        connectionId
      }));

      // 转发SSH输出到WebSocket
      stream.on('data', (data) => {
        ws.send(JSON.stringify({
          type: 'data',
          data: data.toString('utf-8')
        }));
      });

      stream.on('close', () => {
        ws.send(JSON.stringify({
          type: 'disconnected',
          message: 'SSH连接已关闭'
        }));
        ws.close();
      });

      stream.stderr.on('data', (data) => {
        ws.send(JSON.stringify({
          type: 'error',
          data: data.toString('utf-8')
        }));
      });

      // 接收WebSocket消息并转发到SSH
      ws.on('message', async (message) => {
        try {
          const data = JSON.parse(message);

          switch (data.type) {
            case 'input':
              // 终端输入
              if (stream && !stream.destroyed) {
                stream.write(data.data);
              }
              break;

            case 'resize':
              // 终端窗口大小调整
              if (stream && !stream.destroyed) {
                stream.setWindow(data.rows, data.cols);
              }
              break;

            case 'monitor':
              // 请求监控数据
              const monitoring = await monitorService.getServerMonitoring(connectionId);
              ws.send(JSON.stringify({
                type: 'monitoring',
                data: monitoring
              }));
              break;

            case 'start_monitor':
              // 开始定期发送监控数据
              if (!monitorInterval) {
                monitorInterval = setInterval(async () => {
                  try {
                    const monitoring = await monitorService.getSimpleMonitoring(connectionId);
                    ws.send(JSON.stringify({
                      type: 'monitoring',
                      data: monitoring
                    }));
                  } catch (error) {
                    log.error('发送监控数据失败', { error: error.message });
                  }
                }, 3000); // 每3秒更新一次
              }
              break;

            case 'stop_monitor':
              // 停止监控
              if (monitorInterval) {
                clearInterval(monitorInterval);
                monitorInterval = null;
              }
              break;

            default:
              log.warn('未知的消息类型', { type: data.type });
          }
        } catch (error) {
          log.error('处理WebSocket消息失败', { error: error.message });
        }
      });

      // WebSocket关闭处理
      ws.on('close', () => {
        if (monitorInterval) {
          clearInterval(monitorInterval);
        }
        if (connectionId) {
          sshService.disconnect(connectionId);
        }
        log.ssh('WebSocket连接关闭', { userId, serverId });
      });

      ws.on('error', (error) => {
        log.error('WebSocket错误', { error: error.message, userId });
      });

    } catch (error) {
      console.error('❌ WebSocket连接失败详情:', error);
      log.error('WebSocket连接失败', { 
        error: error.message,
        code: error.code,
        stack: error.stack,
        userId 
      });
      ws.send(JSON.stringify({
        type: 'error',
        message: error.message || '连接失败'
      }));
      ws.close();
    }
  });

  return wss;
}

